import express, { Request, Response, Router } from 'express';
import * as bcrypt from 'bcrypt';
import { PrismaClient } from '@prisma/client';
import { ApiResponse } from '../../utils/response';
import { adminAuthMiddleware } from '../../middleware/adminAuth';
import { getUserDailyRewardRate, getTierDailyRate } from '../../utils/tierHelper';
import { DAILY_DISTRIBUTION_COUNT } from '../../constants/reward';
import { addBeijingHours, getBeijingStartOfDay } from '../../utils/timezone';

const router: Router = express.Router();
const prisma = new PrismaClient();

// 获取用户列表（支持搜索和分页）
router.get('/', adminAuthMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const {
      page = 1,
      limit = 20,
      search = '',
      status = '',
      sortBy = 'createdAt',
      sortOrder = 'desc',
      exportAll = 'false' // 新增：导出全部数据参数
    } = req.query;

    const offset = (Number(page) - 1) * Number(limit);

    // 获取当前用户的角色和类型
    const userType = (req as any).userType;
    const userId = (req as any).userId;
    const adminId = (req as any).adminId;
    const adminRole = (req as any).adminRole;
    const isPartner = (req as any).isPartner;

    // 构建搜索条件
    const where: any = {};

    // 如果是推荐人角色，只能查看自己推荐的用户
    if (userType === 'USER' && adminRole === 'REFERRER' && userId) {
      where.referredBy = userId;
    }

    // 如果是合作伙伴，只能查看通过自己邀请码注册的用户
    if (userType === 'ADMIN' && adminRole === 'PARTNER' && isPartner && adminId) {
      where.partnerAdminId = adminId;
    }

    if (search) {
      where.OR = [
        { referralCode: { contains: String(search) } },
        { idNumber: { contains: String(search) } },
        { name: { contains: String(search) } },
        { username: { contains: String(search) } },
        { mobileNumber: { contains: String(search) } }
      ];
    }

    if (status) {
      where.status = status;
    }

    // 判断是否导出全部
    const isExportAll = exportAll === 'true';

    // 获取用户列表
    const users = await prisma.user.findMany({
      where,
      include: {
        balance: true,
        stakingInfo: true,
        _count: {
          select: {
            deposits: true,
            withdraws: true,
            referredUsers: true
          }
        }
      },
      orderBy: { [String(sortBy)]: String(sortOrder) },
      ...(isExportAll ? {} : {
        skip: offset,
        take: Number(limit)
      })
    });

    const userIds = users.map(user => user.id)
    const beijingTodayStart = getBeijingStartOfDay(new Date())
    const beijingTomorrowStart = addBeijingHours(beijingTodayStart, 24)

    let rewardMap: Map<number, { count: number; amount: number }> = new Map()
    if (userIds.length > 0) {
      const rewardStats = await prisma.stakingReward.groupBy({
        by: ['userId'],
        where: {
          userId: { in: userIds },
          createdAt: {
            gte: beijingTodayStart,
            lt: beijingTomorrowStart
          },
          distributionKey: {
            startsWith: 'daily:'
          }
        },
        _count: { id: true },
        _sum: { amount: true }
      })
      rewardMap = new Map(
        rewardStats.map(stat => [
          stat.userId,
          {
            count: stat._count.id,
            amount: Number(stat._sum.amount ?? 0)
          }
        ])
      )
    }

    // 获取总数
    const total = await prisma.user.count({ where });

    // 处理敏感信息
    const sanitizedUsers = users.map(user => ({
      id: user.id,
      idNumber: user.idNumber,
      username: user.username,
      name: user.name,
      birthDateFirst6: user.birthDateFirst6,
      withdrawalBank: user.withdrawalBank,
      withdrawalAccount: user.withdrawalAccount,
      accountHolder: user.accountHolder,
      mobileCarrier: user.mobileCarrier,
      mobileNumber: user.mobileNumber,
      entryCode: user.entryCode,
      status: user.status,
      tier: user.tier, // 添加等级字段
      referralCode: user.referralCode,
      referredBy: user.referredBy,
      createdAt: user.createdAt,
      updatedAt: user.updatedAt,
      lastLoginAt: user.lastLoginAt,
      lastLoginIp: user.lastLoginIp, // 添加最后登录IP
      balance: user.balance ? {
        balance: Number(user.balance.balance),
        frozen: Number(user.balance.frozen),
        total: Number(user.balance.total)
      } : null,
      stats: {
        totalDeposits: user._count.deposits,
        totalWithdraws: user._count.withdraws,
        referredUsersCount: user._count.referredUsers
      },
      stakingProgress: (user.stakingInfo || rewardMap.get(user.id)) ? {
        dailyDistributionCount: rewardMap.get(user.id)?.count ??
          user.stakingInfo?.dailyDistributionCount ?? 0,
        totalSlots: DAILY_DISTRIBUTION_COUNT,
        dailyRewardDistributed: rewardMap.get(user.id)?.amount ??
          Number(user.stakingInfo?.dailyRewardDistributed || 0),
        currentDailyReward: Number(user.stakingInfo?.currentDailyReward || 0)
      } : null
    }));

    res.json(ApiResponse.success({
      users: sanitizedUsers,
      pagination: {
        page: Number(page),
        limit: Number(limit),
        total: Number(total),
        totalPages: Math.ceil(Number(total) / Number(limit))
      }
    }, '사용자 목록 조회에 성공했습니다.'));

  } catch (error) {
    console.error('사용자 목록 조회 오류:', error);
    res.status(500).json(ApiResponse.error('사용자 목록 조회에 실패했습니다.'));
  }
});

// 获取用户详情
router.get('/:id', adminAuthMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const { id } = req.params;
    const userType = (req as any).userType;
    const userId = (req as any).userId;
    const adminId = (req as any).adminId;
    const adminRole = (req as any).adminRole;
    const isPartner = (req as any).isPartner;

    const user = await prisma.user.findUnique({
      where: { id: Number(id) },
      include: {
        balance: true,
        deposits: {
          orderBy: { createdAt: 'desc' },
          take: 10
        },
        withdraws: {
          orderBy: { createdAt: 'desc' },
          take: 10
        },
        stakingInfo: true,
        referredUsers: {
          select: {
            id: true,
            name: true,
            createdAt: true
          }
        },
        referrer: {
          select: {
            id: true,
            name: true,
            referralCode: true
          }
        }
      }
    });

    if (!user) {
      res.status(404).json(ApiResponse.error('사용자를 찾을 수 없습니다.'));
      return;
    }

    // 如果是推荐人，验证该用户是否是自己邀请的
    if (userType === 'USER' && adminRole === 'REFERRER' && userId) {
      if (user.referredBy !== userId) {
        res.status(403).json(ApiResponse.error('해당 사용자 정보에 접근할 수 없습니다.'));
        return;
      }
    }

    // 如果是合作伙伴，验证该用户是否通过自己的邀请码注册
    if (userType === 'ADMIN' && adminRole === 'PARTNER' && isPartner && adminId) {
      if (user.partnerAdminId !== adminId) {
        res.status(403).json(ApiResponse.error('해당 사용자 정보에 접근할 수 없습니다.'));
        return;
      }
    }

    // 处理敏感信息
    const sanitizedUser = {
      id: user.id,
      idNumber: user.idNumber,
      username: user.username,
      name: user.name,
      birthDateFirst6: user.birthDateFirst6,
      withdrawalBank: user.withdrawalBank,
      withdrawalAccount: user.withdrawalAccount,
      accountHolder: user.accountHolder,
      mobileCarrier: user.mobileCarrier,
      mobileNumber: user.mobileNumber,
      entryCode: user.entryCode,
      status: user.status,
      tier: user.tier, // 添加等级字段
      referralCode: user.referralCode,
      referredBy: user.referredBy,
      createdAt: user.createdAt,
      updatedAt: user.updatedAt,
      lastLoginAt: user.lastLoginAt,
      lastLoginIp: user.lastLoginIp, // 添加最后登录IP
      balance: user.balance,
      stakingProgress: user.stakingInfo ? {
        dailyDistributionCount: user.stakingInfo.dailyDistributionCount,
        totalSlots: DAILY_DISTRIBUTION_COUNT,
        dailyRewardDistributed: Number(user.stakingInfo.dailyRewardDistributed || 0),
        currentDailyReward: Number(user.stakingInfo.currentDailyReward || 0)
      } : null,
      stakingInfo: user.stakingInfo,
      recentDeposits: user.deposits,
      recentWithdraws: user.withdraws,
      referredUsers: user.referredUsers,
      referrer: user.referrer
    };

    res.json(ApiResponse.success(sanitizedUser, '사용자 상세 조회에 성공했습니다.'));

  } catch (error) {
    console.error('사용자 상세 조회 오류:', error);
    res.status(500).json(ApiResponse.error('사용자 상세 조회에 실패했습니다.'));
  }
});

// 更新用户상태
router.put('/:id/status', adminAuthMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const { id } = req.params;
    const { status } = req.body;

    // 验证상태值
    const validStatuses = ['ACTIVE', 'INACTIVE', 'SUSPENDED', 'DELETED'];
    if (!validStatuses.includes(status)) {
      res.status(400).json(ApiResponse.error('유효하지 않은 상태 값입니다.'));
      return;
    }

    const updatedUser = await prisma.user.update({
      where: { id: Number(id) },
      data: { status },
      select: {
        id: true,
        name: true,
        idNumber: true,
        status: true,
        updatedAt: true
      }
    });

    res.json(ApiResponse.success(updatedUser, '사용자 상태가 성공적으로 업데이트되었습니다.'));

  } catch (error: any) {
    console.error('사용자 상태 업데이트 오류:', error);
    if (error.code === 'P2025') {
      res.status(404).json(ApiResponse.error('사용자를 찾을 수 없습니다.'));
    } else {
      res.status(500).json(ApiResponse.error('사용자 상태 업데이트에 실패했습니다.'));
    }
  }
});

// 修改用户信息(密码、卡号、电话号)
router.put('/:id/info', adminAuthMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const { id } = req.params;
    const { password, withdrawalAccount, mobileNumber } = req.body;

    const userType = (req as any).userType;
    const adminId = (req as any).adminId;
    const adminRole = (req as any).adminRole;
    const isPartner = (req as any).isPartner;

    // 验证至少提供一个要修改的字段
    if (!password && !withdrawalAccount && !mobileNumber) {
      res.status(400).json(ApiResponse.error('수정할 정보를 입력해 주세요.'));
      return;
    }

    // 验证用户是否存在
    const user = await prisma.user.findUnique({
      where: { id: Number(id) }
    });

    if (!user) {
      res.status(404).json(ApiResponse.error('사용자를 찾을 수 없습니다.'));
      return;
    }

    // 如果是合作伙伴,验证用户是否通过自己的邀请码注册
    if (userType === 'ADMIN' && adminRole === 'PARTNER' && isPartner && adminId) {
      if (user.partnerAdminId !== adminId) {
        res.status(403).json(ApiResponse.error('해당 사용자 정보를 수정할 권한이 없습니다.'));
        return;
      }
    }

    // 构建更新数据
    const updateData: any = {};

    if (password) {
      if (password.length < 6) {
        res.status(400).json(ApiResponse.error('비밀번호는 최소 6자 이상이어야 합니다.'));
        return;
      }
      updateData.password = await bcrypt.hash(password, 12);
    }

    if (withdrawalAccount) {
      updateData.withdrawalAccount = withdrawalAccount;
    }

    if (mobileNumber) {
      updateData.mobileNumber = mobileNumber;
    }

    // 更新用户信息
    const updatedUser = await prisma.user.update({
      where: { id: Number(id) },
      data: updateData,
      select: {
        id: true,
        name: true,
        idNumber: true,
        withdrawalAccount: true,
        mobileNumber: true,
        updatedAt: true
      }
    });

    res.json(ApiResponse.success(updatedUser, '사용자 정보가 성공적으로 업데이트되었습니다.'));

  } catch (error: any) {
    console.error('사용자 정보 업데이트 오류:', error);
    if (error.code === 'P2025') {
      res.status(404).json(ApiResponse.error('사용자를 찾을 수 없습니다.'));
    } else {
      res.status(500).json(ApiResponse.error('사용자 정보 업데이트에 실패했습니다.'));
    }
  }
});

// 获取用户交易记录
router.get('/:id/transactions', adminAuthMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const { id } = req.params;
    const { page = 1, limit = 20, type = 'all' } = req.query;
    const userType = (req as any).userType;
    const userId = (req as any).userId;
    const adminRole = (req as any).adminRole;

    // 如果是推荐人，验证该用户是否是自己邀请的
    if (userType === 'USER' && adminRole === 'REFERRER' && userId) {
      const user = await prisma.user.findUnique({
        where: { id: Number(id) },
        select: { referredBy: true }
      });

      if (!user || user.referredBy !== userId) {
        res.status(403).json(ApiResponse.error('해당 사용자 정보에 접근할 수 없습니다.'));
        return;
      }
    }

    const offset = (Number(page) - 1) * Number(limit);

    let deposits: any[] = [];
    let withdraws: any[] = [];
    let depositsTotal = 0;
    let withdrawsTotal = 0;

    if (type === 'all' || type === 'deposit') {
      deposits = await prisma.depositRecord.findMany({
        where: { userId: Number(id) },
        orderBy: { createdAt: 'desc' },
        skip: type === 'deposit' ? offset : 0,
        take: type === 'deposit' ? Number(limit) : 5
      });

      if (type === 'deposit') {
        depositsTotal = await prisma.depositRecord.count({
          where: { userId: Number(id) }
        });
      }
    }

    if (type === 'all' || type === 'withdraw') {
      withdraws = await prisma.withdrawRecord.findMany({
        where: { userId: Number(id) },
        orderBy: { createdAt: 'desc' },
        skip: type === 'withdraw' ? offset : 0,
        take: type === 'withdraw' ? Number(limit) : 5
      });

      if (type === 'withdraw') {
        withdrawsTotal = await prisma.withdrawRecord.count({
          where: { userId: Number(id) }
        });
      }
    }

    const result = {
      deposits,
      withdraws,
      pagination: type === 'all' ? null : {
        page: Number(page),
        limit: Number(limit),
        total: type === 'deposit' ? depositsTotal : withdrawsTotal,
        totalPages: Math.ceil((type === 'deposit' ? depositsTotal : withdrawsTotal) / Number(limit))
      }
    };

    res.json(ApiResponse.success(result, '거래 기록 조회에 성공했습니다.'));

  } catch (error) {
    console.error('거래 기록 조회 오류:', error);
    res.status(500).json(ApiResponse.error('거래 기록 조회에 실패했습니다.'));
  }
});

// 获取用户持有币信息（包含质押信息）
router.get('/:id/coins', adminAuthMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const { id } = req.params;
    const userType = (req as any).userType;
    const userId = (req as any).userId;
    const adminRole = (req as any).adminRole;

    // 如果是推荐人，验证该用户是否是自己邀请的
    if (userType === 'USER' && adminRole === 'REFERRER' && userId) {
      const user = await prisma.user.findUnique({
        where: { id: Number(id) },
        select: { referredBy: true }
      });

      if (!user || user.referredBy !== userId) {
        res.status(403).json(ApiResponse.error('해당 사용자 정보에 접근할 수 없습니다.'));
        return;
      }
    }

    // 获取用户余额
    const balance = await prisma.userBalance.findUnique({
      where: { userId: Number(id) }
    });

    // 获取用户质押信息
    const staking = await prisma.userStaking.findUnique({
      where: { userId: Number(id) }
    });

    res.json(ApiResponse.success({
      krw: {
        balance: balance ? Number(balance.balance) : 0,
        frozen: balance ? Number(balance.frozen) : 0,
        total: balance ? Number(balance.total) : 0
      },
      staking: staking ? {
        stakedAmount: Number(staking.stakedAmount),
        lockedAmount: Number(staking.lockedAmount),
        totalRewardsNear: Number(staking.totalRewardsNear),
        dailyRewardRate: Number(staking.dailyRewardRate),
        lastSettlementDate: staking.lastSettlementDate
      } : null
    }, '보유 코인 정보 조회에 성공했습니다.'));

  } catch (error) {
    console.error('보유 코인 정보 조회 오류:', error);
    res.status(500).json(ApiResponse.error('보유 코인 정보 조회에 실패했습니다.'));
  }
});

// 获取用户统计信息
router.get('/:id/stats', adminAuthMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const { id } = req.params;

    // 获取充值统计
    const depositStats = await prisma.depositRecord.aggregate({
      where: { userId: Number(id) },
      _sum: { amount: true },
      _count: true
    });

    // 获取提现统计
    const withdrawStats = await prisma.withdrawRecord.aggregate({
      where: { userId: Number(id) },
      _sum: { amount: true },
      _count: true
    });

    // 获取推荐用户数量
    const referralCount = await prisma.user.count({
      where: { referredBy: Number(id) }
    });

    const stats = {
      totalDeposits: depositStats._sum.amount || 0,
      depositCount: depositStats._count,
      totalWithdraws: withdrawStats._sum.amount || 0,
      withdrawCount: withdrawStats._count,
      referralCount: referralCount
    };

    res.json(ApiResponse.success(stats, '사용자 통계 조회에 성공했습니다.'));

  } catch (error) {
    console.error('사용자 통계 조회 오류:', error);
    res.status(500).json(ApiResponse.error('사용자 통계 조회에 실패했습니다.'));
  }
});

// 调整用户锁仓金额
router.post('/:id/adjust-locked', adminAuthMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const { id } = req.params;
    const { lockedAmount } = req.body;

    if (lockedAmount === undefined || lockedAmount < 0) {
      res.status(400).json(ApiResponse.error('락업 금액은 0 이상이어야 합니다.'));
      return;
    }

    // 查询或创建用户质押记录
    const existingStaking = await prisma.userStaking.findUnique({
      where: { userId: Number(id) }
    });

    if (existingStaking) {
      // 更新现有记录
      await prisma.userStaking.update({
        where: { userId: Number(id) },
        data: { lockedAmount: Number(lockedAmount) }
      });
    } else {
      // 创建新记录
      // 获取用户当前等级的日收益率
      const userDailyRate = await getUserDailyRewardRate(Number(id))

      await prisma.userStaking.create({
        data: {
          userId: Number(id),
          stakedAmount: 0,
          lockedAmount: Number(lockedAmount),
          totalRewardsNear: 0,
          dailyRewardRate: userDailyRate // 使用用户当前等级的日收益率
        }
      });
    }

    res.json(ApiResponse.success({
      userId: Number(id),
      lockedAmount: Number(lockedAmount)
    }, '락업 금액이 성공적으로 조정되었습니다.'));

  } catch (error) {
    console.error('락업 금액 조정 오류:', error);
    res.status(500).json(ApiResponse.error('락업 금액 조정에 실패했습니다.'));
  }
});

// 修改用户等级
router.put('/:id/tier', adminAuthMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const { id } = req.params;
    const { tier } = req.body; // ENTRY/BASIC/NORMAL/ROYAL/VIP/VVIP

    // 验证等级值是否有效
    const validTiers = ['ENTRY', 'BASIC', 'NORMAL', 'ROYAL', 'VIP', 'VVIP'];
    if (!validTiers.includes(tier)) {
      res.status(400).json(ApiResponse.error('유효하지 않은 등급 값입니다.'));
      return;
    }

    // 验证用户是否存在
    const user = await prisma.user.findUnique({
      where: { id: Number(id) }
    });

    if (!user) {
      res.status(404).json(ApiResponse.error('사용자를 찾을 수 없습니다.'));
      return;
    }

    // 获取新等级的收益率配置
    const tierConfig = await prisma.tierConfig.findUnique({
      where: { tier }
    });

    if (!tierConfig) {
      res.status(400).json(ApiResponse.error('등급 설정을 찾을 수 없습니다.'));
      return;
    }

    const newDailyRate = Number(tierConfig.dailyRate);

    // 事务处理：同时更新用户等级和质押收益率
    await prisma.$transaction(async (tx) => {
      // 更新用户等级
      await tx.user.update({
        where: { id: Number(id) },
        data: { tier }
      });

      // 同步更新质押收益率（如果有质押记录）
      const stakingInfo = await tx.userStaking.findUnique({
        where: { userId: Number(id) }
      });

      if (stakingInfo) {
        await tx.userStaking.update({
          where: { userId: Number(id) },
          data: { dailyRewardRate: newDailyRate }
        });
      }
    });

    res.json(ApiResponse.success({
      userId: Number(id),
      oldTier: user.tier,
      newTier: tier,
      newDailyRate,
      newAnnualRate: Number(tierConfig.annualRate)
    }, `사용자 등급이 ${user.tier}에서 ${tier}로 성공적으로 업데이트되었습니다.`));

  } catch (error) {
    console.error('사용자 등급 업데이트 오류:', error);
    res.status(500).json(ApiResponse.error('사용자 등급 업데이트에 실패했습니다.'));
  }
});

// 删除用户
router.delete('/:id', adminAuthMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const { id } = req.params;
    const userId = Number(id);

    const result = await prisma.$transaction(async (tx) => {
      // 验证用户是否存在
      const user = await tx.user.findUnique({ where: { id: userId } });
      if (!user) {
        throw new Error('USER_NOT_FOUND');
      }

      // 级联删除所有关联数据（按依赖顺序）
      // 注意: upbitTransaction 和 stakingApplication 表已删除
      await tx.referralSettings.deleteMany({ where: { userId } });
      await tx.stakingHistory.deleteMany({ where: { userId } });
      await tx.stakingReferralReward.deleteMany({ where: { userId } });
      await tx.referralReward.deleteMany({ where: { userId } });
      await tx.stakingReward.deleteMany({ where: { userId } });
      await tx.userStaking.deleteMany({ where: { userId } });
      await tx.withdrawRecord.deleteMany({ where: { userId } });
      await tx.depositRecord.deleteMany({ where: { userId } });
      await tx.userBalance.deleteMany({ where: { userId } });

      // 处理推荐关系 - 将被删除用户的下级推荐人的推荐人ID设为null
      await tx.user.updateMany({
        where: { referredBy: userId },
        data: { referredBy: null }
      });

      // 最后删除用户本身
      await tx.user.delete({ where: { id: userId } });

      return { deletedUserId: userId, deletedUserName: user.name };
    });

    res.json(ApiResponse.success(result, '사용자 삭제 완료'));

  } catch (error: any) {
    console.error('사용자 삭제 오류:', error);
    if (error.message === 'USER_NOT_FOUND') {
      res.status(404).json(ApiResponse.error('사용자를 찾을 수 없습니다'));
    } else if (error.code === 'P2025') {
      res.status(404).json(ApiResponse.error('사용자를 찾을 수 없습니다'));
    } else {
      res.status(500).json(ApiResponse.error('사용자 삭제에 실패했습니다'));
    }
  }
});

export default router;
